/*
 * @Author: silence silence9685@163.com
 * @Date: 2023-04-21 15:04:48
 * @LastEditors: silence silence9685@163.com
 * @LastEditTime: 2023-07-27 14:12:32
 * @FilePath: \lenercom_bluetooth_app\lib\common\widgets\cubitWidget\InputView.dart
 * @Description: 输入试图：标题+内容
 */
import 'dart:async';

import 'package:ems_neutral_app/pages/Mine/Language/SilLocalizations/SilLocalizations.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sil_base_widget_package/sil_base_widget_package.dart';
import 'package:sil_base_widget_package/tools/SilUtilsTools.dart';
import 'package:sil_utils_package/extension/StringExtension.dart';
import 'package:sil_utils_package/tools/SilTools.dart';

import '../../../api/ApiUtils.dart';
import '../../../api/request/CommonRequest.dart';
import '../../../utils/color/ColorUtils.dart';
import '../../Method/CommonMethod.dart';

enum InputViewType {
  InputViewTypeNormal, // 普通
  InputViewTypePassword, // 密码
  InputViewTypePhone, // 手机号
  InputViewTypeEmail, // 邮箱
  InputViewTypeCode, // 验证码
}

/// 发送验证码类型
enum CodeType{
  CodeTypeByPhone,
  CodeTypeByEmail
}

class InputView extends StatefulWidget {
  final String? title;

  /// 占位文字
  final String? hintText;

  /// 输入类型
  final InputViewType inputViewType;
  final EdgeInsetsGeometry? margin;

  /// 设置输入内容间距
  final EdgeInsetsGeometry? inputViewMargin;

  /// 右侧显示发送验证码，默认不显示
  final bool showSendCode;
  final String? account;

  /// 发送验证码类型
  final CodeType? codeType;

  /// 显示的值
  final String? value;

  /// 右侧view
  final Widget? rightView;

  /// 左侧view
  final Widget? leftView;

  /**
   * valid:输入框内容是否有效
   * value:输入框内容
   */
  final Function(bool valid, String value) onValid;

  /// 点击输入文本
  final Function()? onClickTextField;

  /// 是否显示右侧删除按钮,默认显示
  final bool showClearBtn;

  /// 隐藏标题,默认不隐藏
  final bool hideTitle;

  const InputView(
      {required this.title,
      required this.onValid,
      this.inputViewType = InputViewType.InputViewTypeNormal,
      this.margin,
      this.hintText,
      this.showSendCode = false,
      this.account,
      this.codeType = CodeType.CodeTypeByPhone,
      this.value,
      this.rightView,
      this.onClickTextField,
      this.showClearBtn = true,
      this.leftView,
      this.hideTitle = false,
      this.inputViewMargin,
      Key? key})
      : super(key: key);

  @override
  State<InputView> createState() => _InputViewState();
}

class _InputViewState extends State<InputView> {
  late SilFormattersInterface _interface;
  bool _isCanSendCode = true;
  int _countSecond = 120;
  Timer? _timer = null;

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();

    switch (widget.inputViewType) {
      case InputViewType.InputViewTypeCode:
        _interface = SilFormattersPhoneCode();
        break;
      case InputViewType.InputViewTypePhone:
        _interface = SilFormattersPhone();
        break;
      case InputViewType.InputViewTypeEmail:
        _interface = SilFormattersEmail();
        break;
      case InputViewType.InputViewTypePassword:
        _interface = SilFormattersPwd();
        break;
      default:
        _interface = SilFormattersEmail();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: widget.margin ?? EdgeInsets.only(bottom: 8.w),
      child: Column(
        children: [
          /// 标题
        if(!widget.hideTitle)
          Container(
              margin: EdgeInsets.only(bottom: 8.w),
              alignment: Alignment.bottomLeft,
              height: 20.w,
              child: SilText(
                this.widget.title,
                color: ColorUtils.color_font_main,
                textAlign: TextAlign.left,
                fontWeight: FontWeight.w400,
                fontSize: 14.sp,
              )),

          /// 输入内容
          SilEmptyButton(
              useConstrained: true,
              padding: widget.inputViewMargin ?? EdgeInsets.symmetric(horizontal: 16.w),
              radius: 6.w,
              backgroundColor: ColorUtils.color_input_bg,
              child: Row(
                children: [
                  /// 左侧
                  if(widget.leftView != null) widget.leftView!,
                  
                  Expanded(
                      child: SilTextField(
                    onValid: ((valid, value) {
                      widget.onValid(valid, value);
                    }),
                    onClick: widget.onClickTextField,
                    enabled: widget.onClickTextField == null,
                    hintText: widget.hintText,
                    interface: _interface,
                    text: widget.value,
                    showClearBtn: widget.showClearBtn,
                    isObscure: widget.inputViewType ==
                        InputViewType.InputViewTypePassword,
                  )),

                  /// 右侧显示发送验证码按钮
                  if (widget.showSendCode) sendCode(),

                  /// 右侧view
                  if (widget.rightView != null) widget.rightView!,
                ],
              ))
        ],
      ),
    );
  }

  sendCode() {
    String firstPrompt = LangOf(context)?.common?.get_code ?? '获取验证码';
    String secondPrompt = LangOf(context)?.common?.regain ?? '重新获取';

    return Container(
        margin: EdgeInsets.only(left: 60.w),
        child: SilButton(
          title: _isCanSendCode
              ? firstPrompt
              : "${secondPrompt}(${_countSecond}s)",
          fontSize: 12.sp,
          fontWeight: FontWeight.w400,
          titleColor: ColorUtils.color_theme, //ColorUtils.color_font_minor,
          onTapFunc: _onMessageCode,
        ));
  }

  /// 获取短信验证码
  Future<void> _onMessageCode() async {
    // 隐藏键盘
    globalTextFieldDismiss(context);

    String? email, phone;
    if (widget.codeType == CodeType.CodeTypeByPhone) {
      phone = widget.account;

      /// 手机号
      if (SilTools.stringIsEmpty(phone)) {
        String prompt = LangOf(context)?.common?.phone_notEmpty ?? '手机号不能为空';
        SilToast.show(prompt);
        return;
      }

      if (phone?.phoneNumber() == false) {
        String prompt =
            LangOf(context)?.common?.phone_correctFormat ?? '请输入正确的手机格式';
        SilToast.show(prompt);
        return;
      }
    } else if (widget.codeType == CodeType.CodeTypeByEmail) {
      email = widget.account;

      /// 邮箱
      if (SilTools.stringIsEmpty(email)) {
        String prompt = LangOf(context)?.common?.email_notEmpty ?? '邮箱不能为空';
        SilToast.show(prompt);
        return;
      }

      if (email?.email() == false) {
        String prompt =
            LangOf(context)?.common?.email_correctFormat ?? '请输入正确的email格式';
        SilToast.show(prompt);
        return;
      }
    }

    if (_isCanSendCode == false) {
      String? prompt = LangOf(context)?.common?.second_sLater;
      if (!SilTools.stringIsEmpty(prompt)) {
        prompt = '120$prompt';
      }
      SilToast.show(prompt ?? ' 请一分钟后再试 ');
      return;
    }

    apiShow(context, api: api_send_code(email: email, phone: phone),
        success: (result) {
      String prompt = LangOf(context)?.common?.codeSend ?? '验证码已发送';
      SilToast.show(prompt);
      const period = const Duration(seconds: 1);
      _timer = Timer.periodic(period, (timer) {
        _isCanSendCode = false;
        _countSecond--;
        if (_countSecond == 0) {
          _countSecond = 120;
          _isCanSendCode = true;
          _timer?.cancel();
        }

        if (mounted) {
          setState(() {});
        }
      });
    }, showErrorToast: true, showLoading: true);
  }
}

/**
 * 邮箱输入框
 */
class SilFormattersEmail implements SilFormattersInterface {
  @override
  List<TextInputFormatter> inputFormatters(int? min, int? max) {
    return [
      LengthLimitingTextInputFormatter(max ?? 100),
    ];
  }

  @override
  bool checkValid(String value, int? min, int? max) {
    bool valid = false;

    if (!SilUtilsTools.stringIsEmpty(value)) {
      if (value.email()) {
        valid = true;
      }
    }

    return valid;
  }

  @override
  TextInputType type = TextInputType.text;
}
